﻿#include"SeqList.h"

//初始化函数		初始化数据，指针置为空，普通变量置为0
void SLInit(SL* ps)
{
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

//打印函数		以表中目前的数据进行遍历打印
void SLPrint(SL* ps)
{
	assert(ps);//断言一下是否传进来空指针
	if (ps->size == 0)
	{
		printf("当前数据为零哦~本顺序表才没法打印勒~(▼皿▼#)\n");
		return;//结束此函数
	}

	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

//判断是否已经满了还是是否存在		无需声明
void SLCheckCapacity(SL* ps)
{
	//首先判断是否达到更改条件(上面两个条件的共同点就是size和capacity相等)
	if (ps->size == ps->capacity)
	{
		int newcapcity = ps->capacity == 0 ? 4 : ps->capacity * 2;//一开始开4个SLDataType空间，否则就是原本的空间乘以2
		SLDataType* temp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newcapcity);
		if (temp == NULL)//如果申请堆内存失败
		{
			printf("人家才没有出问题呢！(；д；)(realloc 失败 --)\n");
			exit(-1);//无法申请堆内存程序直接结束吧
		}
		ps->a = temp;
		ps->capacity = newcapcity;
	}

}

//指定插入		1.首先进行判断数组是否满了还是不存在 2.然后从此位置元素开始往后移动 3.此位置填充元素  4.判断传入的pos是否正确
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	if (pos > ps->size || pos < 0)
	{
		printf("现在存储第%d个了，要按顺序存储哦！记住没！下次不准这样啦！(▼ヘ▼#)\n", ps->size + 1);
		return;
	}
	
	//注意当pos为size时一样成立 无需移动
	for (int i = ps->size - 1; i >= pos; i--)
	{
		ps->a[i + 1] = ps->a[i];//从最后一个元素开始往后移动，直到目标下标也移动了，此时位置空出来了
	}
	ps->a[pos] = x;//此位置填充元素
	ps->size++;
}

//指定删除		1.判断是否为空	2.从此下标开始，后面元素依次往前移动一位 3.判断传入的pos是否正确
void SLErase(SL* ps, int pos)
{
	assert(ps);
	if (pos >= ps->size || pos < 0)//注意此时如果乱标注下标 size还是会减少的
	{
		printf("哇~(▼へ▼メ)你这个人,都没有还怎么删哇！\n");
		return;
	}

	//从后往前覆盖了即删除
	for (int i = pos; i < ps->size - 1; i++)//注意最后一个覆盖的数为 ps->size - 2 = ps->size -2 + 1
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
	printf("删除执行完成ᕦ(･ㅂ･)ᕤ！现在还剩%d个数哦~\n", ps->size);
}

//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLInsert(ps, 0, x);//头插就是对0下标进行插入即可
}

//头删
void SLPopFront(SL* ps)
{
	assert(ps);
	SLErase(ps, 0);//对0下标进行删除
}

//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLInsert(ps, ps->size, x);//对最后一个下标最后一个数进行插入
}

//尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	SLErase(ps, ps->size - 1);//对最后一个下标进行删除揭开
}

//查找数据		利用循环遍历进行查找，二分法需要进行排序哦~	找到了返回第一个下标，找不到返回-1
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
			return i + 1;
	}
	return -1;
}

//修改数据
void SLModify(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	if (pos >= ps->size || pos < 0)
	{
		printf("当前数据范围是是[%d, %d]，你能正确的给我操作嘛(▼へ▼メ)(▼皿▼#)\n", (ps->size == 0? 0 : 1), ps->size);
		return;
	}
	ps->a[pos] = x;
}

//程序结束回收堆内存：
void SLDel(SL* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}